/* 
Copyright (c) 2004,2005, 2006, 2007, 2008 University of Illinois 

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

3. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
Mozilla Accessibility Extension
listofforms.js
JavaScript code for the list of forms XUL component
*/

AccessibilityExtension.ns(function() { with (AccessibilityExtension.LIB) {

	var AE = AccessibilityExtension.ns;  
	AE.dialogName = "accessext-form-list-forms";

	var formsarray = null; // this is only used to pull all of the form element into dataarray
	var curForm = -1;
	
AccessibilityExtension.LIB.extend(AccessibilityExtension.LIB,
{	
	updatePointers_custom: function() {
		if (window.opener.name == 'accessext-issues') {
			var accessibilityIssuesDialog = window.opener.parent;
			AE.thewindow = accessibilityIssuesDialog.opener.parent._content;			
		} else {
			AE.thewindow = window.opener.parent._content;
		}
		AE.mydoc = AE.thewindow.document;
		AE.treebox = document.getElementById("treebox");
		formsarray = new Array();
		AE.dataarray = new Array();
	},
	
	FindLabelNodeForId: function(id,doc) {
		var a_labels = doc.getElementsByTagName("label");
		var i;
		for(i = 0; i < a_labels.length; i ++) {
			var m_node = a_labels[i];
			if(m_node.getAttribute) {
				var label = m_node.getAttribute("for");
				if(label == id) {
					return m_node;
				}
			}
		}
		return null;
	},
	
	FindLabelFromParents: function(node) {
		var lookingNode = node.parentNode;
		while ((lookingNode != null) && (lookingNode.nodeName !="FORM") && (lookingNode.nodeName!="LABEL")) {
			lookingNode = lookingNode.parentNode;
		}
	
		if ((lookingNode != null) && (lookingNode.nodeName=="LABEL")) {
			return getDisplayableTextRecursively(lookingNode);
		}
	
		return false;
	},
	
	FindLabelForId: function(node, id) {
		if(!id) {
			return "";
		}
		
		var labelNode = FindLabelNodeForId(id,node.ownerDocument);
		if (labelNode != null) {
			return getDisplayableTextRecursively(node);
		}
		//If we get this far, then we have not found a label. Now look up at node's parents
		return FindLabelFromParents(node);
	},
	
	GetLegendForNode: function(node) {
		//Seek upward until we reach a fieldset node
		var lookingNode = node.parentNode;
		while ((lookingNode != null) && (lookingNode.nodeName !="FIELDSET") && (lookingNode.nodeName != "FORM")) {
			lookingNode = lookingNode.parentNode;
		}
		
		if (lookingNode != null) {
			if (lookingNode.nodeName == "FIELDSET") {
				//We now have the fieldset, look for the legend attribute
				labelNodes = lookingNode.getElementsByTagName("LEGEND");
				if (labelNodes.length == 1) {
					return getDisplayableTextRecursively(labelNodes[0]);
				}
			}
		}
		return accessext_getBundleSingleString('forms.noLegend');
	},
	
	/***************************** DIALOG BOX FUNCTIONS ***********************/
	post_InitAccessibilityExt: function() {
		accessext_loadDialogPrefs();
		accessext_setNoteCaption();
		accessext_setNoteText(0);
		loadWairolesProperties();
	},
	
	
	ParseDocumentForFormElements: function(doc, loadArray) {
		// the following lines were added to work with FireBug A11y Extension
		if (AE.dataarray==undefined) { AE.dataarray = loadArray; AE.FBcall = true;} //else {AE.FBcall = false;}
		if (AE.mydoc==undefined) { AE.mydoc = doc; AE.FBcall = true;} //else {AE.FBcall = false;}
		// todo: set AE.thewindow if called from FB (AE.thewindow==undefined) AE.thewindow = doc; 
		
		FBTrace.sysout("Trying to get form information")
		formsarray = parseAndLoadFormObjects(doc);  //also fills dataarray with all form elements
		FBTrace.sysout("Finished getting form information")
	
		var xpathResult = parseWidgetsFromDOM(doc); 
		var r = xpathResult.iterateNext();
		while (r) {
			if (r != null) {
				// only add widgets who's role parent is select, widget, group
				var role = readRole(r);
				var roleLocation = getRoleLocation(role);
				if (roleLocation != -1) {
					if (AE.wairoleProperties[roleLocation].subClassOf[0] == 'select' ||
						AE.wairoleProperties[roleLocation].subClassOf[0] == 'widget' ||
						AE.wairoleProperties[roleLocation].subClassOf[0] == 'group' ) {
						var widObj = newWidgetObject(loadArray.length + 1, r);
						// display the form element version of the widget
						widObj.displayDetails = getFormElementDisplayDetails();
						widObj.fromformname = accessext_getBundleSingleString("forms.widgetElements");
						widObj.displayOrder = this.order - 1;
						widObj.label = widObj.getStateValueInPage('labelledby'); 
						if (widObj.label != '') {
				   			widObj.sourceText = accessext_getBundleSingleString("forms.source.labelledby");
						} else {
							widObj.source = AE.source_none;
				   			widObj.sourceText = accessext_getBundleSingleString("forms.source.none");
						}
						loadArray[loadArray.length] = widObj;
					}
				}
			} 
			r = xpathResult.iterateNext();
		}
	},
	
	RefreshList_custom: function() {
		try {
			var widgetFormObj;
			
			updatePointers();
	
		   var documents = accessext_getDocuments(AE.thewindow,new Array());
		   ParseDocumentForFormElements(documents[0], AE.dataarray);
			UpdateTreeView(); 
		} catch (ex) {
			accessext_consoleDump('RefreshList_custom exception: ', ex);
		}
	},
	
	handleElementTreebox: function() {
		var alt_label = document.getElementById("label-alt-text");
		
		var index = accessext_getActiveValue(AE.treebox);
	
		if (index < 0 || index >= AE.dataarray.length) {
			return;
		}
		var node = AE.dataarray[index];
		if (node) {
			if(node.alt) {	
				alt_label.value = node.alt;
			}
		}
		accessext_treeboxScrollAndHighlightNode(); 
			
		accessext_setNoteText(index);
	},
	
	UpdateTreeView: function() {
		var sc = document.getElementById(AE.sortColumn);
		if (sc == null) {
			accessext_consoleDump("Could not find column: " + AE.sortColumn);
			return;
		}
		
		//Clear the children and create a new one
		var treeChildren = accessext_clearTreeItems(AE.treebox);
	
		//Sort
		//First clear all directions
		var cols = AE.treebox.getElementsByTagName("treecols");
		if (cols.length == 1) {
			for (var i = 0; i < cols[0].childNodes.length; i ++) {
				cols[0].childNodes[i].setAttribute("sortDirection","");
			}
		}
	
		sc.setAttribute("sortDirection", AE.sortDirectionAscending ? "ascending" : "descending");
		switch (AE.sortColumn) {
			case "list-header-order":
				AE.sortProperty="order";
			break;
			case "list-header-main-name":
				AE.sortProperty="fromformname";
			break;
			case "list-header-id":
				AE.sortProperty="id";
			break;
			case "list-header-taborder":
				AE.sortProperty="tabOrder";
			break;
			case "list-header-label":
				AE.sortProperty="label";
			break;
			case "list-header-type":
				AE.sortProperty="type";
			break;
			case "list-header-text":
				AE.sortProperty="text";
			break;
			case "list-header-source":
				AE.sortProperty="source";
			break;		
			default:
				AE.sortProperty="order";
			break;
		}
		
		AE.dataarray.sort(accessext_sortColumnElements);
		//Finally add elements to the list
		for (i = 0; i < AE.dataarray.length; i ++) {
			if (AE.dataarray[i].display) {
				var treeItem = AE.dataarray[i].getTreeItem(document);
				treeItem.setAttribute("value",i);
				treeChildren.appendChild(treeItem);
			}
		}
	},
	
	Focus: function() {
		var theindex = accessext_getActiveValue(AE.treebox);
		CleanUp();
		if(theindex < 0 || theindex >= AE.dataarray.length) {
			return false;
		}
		var node = AE.dataarray[theindex].node;
		if(node.focus) {
			node.focus();
		} else if(node.activate) {
			node.activate();
		} else if(node.click) {
			node.click();
		} else {
			alert(accessext_getBundleSingleString('error.cantFocus'));
		}
	
		return true;
	},
	
	toggleShowSrcColumn: function() {
		var elemChkShowSrc = document.getElementById("checkbox-show-source");
		var element = document.getElementById("list-header-source");
		element.hidden = !elemChkShowSrc.checked;
	},
	
	accessext_MoveToNode: function() {
		/* A little different for this one
			If only a form is selected, move the cursor to the beginning of the form
			If a form control is selected (second list), then focus on the form control
		*/
		
		//First, see if a form control is selected
		if (Focus()) {
			return true;
		}
		
		var theindex;
		
		if (primaryarray.length == 1) {
			theindex = 0;
		} else  {
			theindex = accessext_getActiveValue(AE.treebox_main);
		}
		
		if (theindex  < 0)
			return false;
	
		var node = primaryarray[theindex].node;
		if (node == null) {
			return false;
		}
		accessext_keyboardFocusNode(node,AE.thewindow);
		return true;
	},
	
	CleanUp: function() {
		return accessext_GlobalCleanup();
	}
});
if (AccessibilityExtension.LIB.InitAccessibilityExt) AccessibilityExtension.LIB.InitAccessibilityExt();	
}});